using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using JGSY.CMS.LowCode.Platform.Domain.Entities;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 租户资源配额管理API控制器
    /// </summary>
    [ApiController]
    [Route("api/tenant-resource-quota")]
    [Authorize]
    public class TenantResourceQuotaController : ControllerBase
    {
        private readonly ITenantResourceQuotaService _quotaService;
        private readonly ILogger<TenantResourceQuotaController> _logger;

        public TenantResourceQuotaController(
            ITenantResourceQuotaService quotaService,
            ILogger<TenantResourceQuotaController> logger)
        {
            _quotaService = quotaService;
            _logger = logger;
        }

        #region 配额管理基本操作

        /// <summary>
        /// 获取租户配额信息
        /// </summary>
        [HttpGet("{tenantId}")]
        public async Task<IActionResult> GetQuota(Guid tenantId)
        {
            try
            {
                var result = await _quotaService.GetQuotaAsync(tenantId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取租户配额信息失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "获取租户配额信息失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 创建租户配额
        /// </summary>
        [HttpPost("{tenantId}")]
        public async Task<IActionResult> CreateQuota(Guid tenantId, [FromBody] object request)
        {
            try
            {
                var result = await _quotaService.CreateQuotaAsync(tenantId, request);
                return CreatedAtAction(nameof(GetQuota), new { tenantId }, result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建租户配额失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "创建租户配额失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 更新租户配额
        /// </summary>
        [HttpPut("{tenantId}")]
        public async Task<IActionResult> UpdateQuota(Guid tenantId, [FromBody] object request)
        {
            try
            {
                var result = await _quotaService.UpdateQuotaAsync(tenantId, request);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新租户配额失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "更新租户配额失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 删除租户配额
        /// </summary>
        [HttpDelete("{tenantId}")]
        public async Task<IActionResult> DeleteQuota(Guid tenantId)
        {
            try
            {
                await _quotaService.DeleteQuotaAsync(tenantId);
                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除租户配额失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "删除租户配额失败", error = ex.Message });
            }
        }

        #endregion

        #region 资源使用情况

        /// <summary>
        /// 获取资源使用情况
        /// </summary>
        [HttpGet("{tenantId}/usage")]
        public async Task<IActionResult> GetUsage(Guid tenantId)
        {
            try
            {
                var result = await _quotaService.GetUsageAsync(tenantId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取资源使用情况失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "获取资源使用情况失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取资源使用历史
        /// </summary>
        [HttpGet("{tenantId}/usage/history")]
        public async Task<IActionResult> GetUsageHistory(
            Guid tenantId, 
            [FromQuery] DateTime? startTime = null, 
            [FromQuery] DateTime? endTime = null)
        {
            try
            {
                var result = await _quotaService.GetUsageHistoryAsync(tenantId, startTime, endTime);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取资源使用历史失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "获取资源使用历史失败", error = ex.Message });
            }
        }

        #endregion

        #region 配额检查

        /// <summary>
        /// 检查存储配额
        /// </summary>
        [HttpGet("{tenantId}/check/storage")]
        public async Task<IActionResult> CheckStorageQuota(
            Guid tenantId, 
            [FromQuery] long additionalSize = 0)
        {
            try
            {
                var result = await _quotaService.CheckStorageQuotaAsync(tenantId, additionalSize);
                return Ok(new { allowed = result, message = result ? "存储配额充足" : "存储配额不足" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查存储配额失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "检查存储配额失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 检查用户配额
        /// </summary>
        [HttpGet("{tenantId}/check/users")]
        public async Task<IActionResult> CheckUserQuota(
            Guid tenantId, 
            [FromQuery] int additionalUsers = 0)
        {
            try
            {
                var result = await _quotaService.CheckUserQuotaAsync(tenantId, additionalUsers);
                return Ok(new { allowed = result, message = result ? "用户配额充足" : "用户配额不足" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查用户配额失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "检查用户配额失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 检查API调用配额
        /// </summary>
        [HttpGet("{tenantId}/check/api-calls")]
        public async Task<IActionResult> CheckApiCallQuota(
            Guid tenantId, 
            [FromQuery] int additionalCalls = 0)
        {
            try
            {
                var result = await _quotaService.CheckApiCallQuotaAsync(tenantId, additionalCalls);
                return Ok(new { allowed = result, message = result ? "API调用配额充足" : "API调用配额不足" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查API调用配额失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "检查API调用配额失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 检查带宽配额
        /// </summary>
        [HttpGet("{tenantId}/check/bandwidth")]
        public async Task<IActionResult> CheckBandwidthQuota(
            Guid tenantId, 
            [FromQuery] long additionalBandwidth = 0)
        {
            try
            {
                var result = await _quotaService.CheckBandwidthQuotaAsync(tenantId, additionalBandwidth);
                return Ok(new { allowed = result, message = result ? "带宽配额充足" : "带宽配额不足" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "检查带宽配额失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "检查带宽配额失败", error = ex.Message });
            }
        }

        #endregion

        #region 配额预警

        /// <summary>
        /// 获取配额预警列表
        /// </summary>
        [HttpGet("{tenantId}/alerts")]
        public async Task<IActionResult> GetQuotaAlerts(Guid tenantId)
        {
            try
            {
                var result = await _quotaService.GetQuotaAlertsAsync(tenantId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取配额预警列表失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "获取配额预警列表失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 创建配额预警
        /// </summary>
        [HttpPost("{tenantId}/alerts")]
        public async Task<IActionResult> CreateQuotaAlert(Guid tenantId, [FromBody] object request)
        {
            try
            {
                var result = await _quotaService.CreateQuotaAlertAsync(tenantId, request);
                return CreatedAtAction(nameof(GetQuotaAlerts), new { tenantId }, result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建配额预警失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "创建配额预警失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 更新配额预警
        /// </summary>
        [HttpPut("alerts/{alertId}")]
        public async Task<IActionResult> UpdateQuotaAlert(Guid alertId, [FromBody] object request)
        {
            try
            {
                var result = await _quotaService.UpdateQuotaAlertAsync(alertId, request);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新配额预警失败 for alert {AlertId}", alertId);
                return StatusCode(500, new { message = "更新配额预警失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 删除配额预警
        /// </summary>
        [HttpDelete("alerts/{alertId}")]
        public async Task<IActionResult> DeleteQuotaAlert(Guid alertId)
        {
            try
            {
                await _quotaService.DeleteQuotaAlertAsync(alertId);
                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除配额预警失败 for alert {AlertId}", alertId);
                return StatusCode(500, new { message = "删除配额预警失败", error = ex.Message });
            }
        }

        #endregion

        #region 配额统计

        /// <summary>
        /// 获取配额统计信息
        /// </summary>
        [HttpGet("{tenantId}/statistics")]
        public async Task<IActionResult> GetQuotaStatistics(Guid tenantId)
        {
            try
            {
                var result = await _quotaService.GetQuotaStatisticsAsync(tenantId);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取配额统计信息失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "获取配额统计信息失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取所有租户配额统计
        /// </summary>
        [HttpGet("statistics/all")]
        public async Task<IActionResult> GetAllTenantsQuotaStatistics()
        {
            try
            {
                var result = await _quotaService.GetAllTenantsQuotaStatisticsAsync();
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取所有租户配额统计失败");
                return StatusCode(500, new { message = "获取所有租户配额统计失败", error = ex.Message });
            }
        }

        #endregion

        #region 配额重置

        /// <summary>
        /// 重置特定资源类型的配额使用情况
        /// </summary>
        [HttpPost("{tenantId}/reset/{resourceType}")]
        public async Task<IActionResult> ResetQuotaUsage(Guid tenantId, string resourceType)
        {
            try
            {
                await _quotaService.ResetQuotaUsageAsync(tenantId, resourceType);
                return Ok(new { message = $"已重置 {resourceType} 配额使用情况" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "重置配额使用情况失败 for tenant {TenantId}, resource {ResourceType}", tenantId, resourceType);
                return StatusCode(500, new { message = "重置配额使用情况失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 重置所有配额使用情况
        /// </summary>
        [HttpPost("{tenantId}/reset/all")]
        public async Task<IActionResult> ResetAllQuotaUsage(Guid tenantId)
        {
            try
            {
                await _quotaService.ResetAllQuotaUsageAsync(tenantId);
                return Ok(new { message = "已重置所有配额使用情况" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "重置所有配额使用情况失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "重置所有配额使用情况失败", error = ex.Message });
            }
        }

        #endregion

        #region 批量操作

        /// <summary>
        /// 根据租户ID列表获取配额信息
        /// </summary>
        [HttpPost("batch/get")]
        public async Task<IActionResult> GetQuotasByTenantIds([FromBody] List<Guid> tenantIds)
        {
            try
            {
                var result = await _quotaService.GetQuotasByTenantIdsAsync(tenantIds);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量获取配额信息失败 for {Count} tenants", tenantIds?.Count ?? 0);
                return StatusCode(500, new { message = "批量获取配额信息失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 批量更新配额
        /// </summary>
        [HttpPut("batch/update")]
        public async Task<IActionResult> UpdateMultipleQuotas([FromBody] List<object> requests)
        {
            try
            {
                await _quotaService.UpdateMultipleQuotasAsync(requests);
                return Ok(new { message = "批量更新配额成功" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量更新配额失败 for {Count} requests", requests?.Count ?? 0);
                return StatusCode(500, new { message = "批量更新配额失败", error = ex.Message });
            }
        }

        #endregion

        #region 导出功能

        /// <summary>
        /// 导出单个租户配额报告
        /// </summary>
        [HttpGet("{tenantId}/export")]
        public async Task<IActionResult> ExportQuotaReport(
            Guid tenantId, 
            [FromQuery] string format = "xlsx")
        {
            try
            {
                var result = await _quotaService.ExportQuotaReportAsync(tenantId, format);
                return File(result, GetContentType(format), $"quota-report-{tenantId}-{DateTime.UtcNow:yyyyMMddHHmmss}.{format}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出配额报告失败 for tenant {TenantId}", tenantId);
                return StatusCode(500, new { message = "导出配额报告失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 导出所有租户配额报告
        /// </summary>
        [HttpGet("export/all")]
        public async Task<IActionResult> ExportAllTenantsQuotaReport([FromQuery] string format = "xlsx")
        {
            try
            {
                var result = await _quotaService.ExportAllTenantsQuotaReportAsync(format);
                return File(result, GetContentType(format), $"all-tenants-quota-report-{DateTime.UtcNow:yyyyMMddHHmmss}.{format}");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出所有租户配额报告失败");
                return StatusCode(500, new { message = "导出所有租户配额报告失败", error = ex.Message });
            }
        }

        #endregion

        #region 私有方法

        /// <summary>
        /// 根据格式获取Content-Type
        /// </summary>
        private static string GetContentType(string format)
        {
            return format.ToLower() switch
            {
                "xlsx" => "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
                "csv" => "text/csv",
                "pdf" => "application/pdf",
                "json" => "application/json",
                _ => "application/octet-stream"
            };
        }

        #endregion
    }
}
